﻿#region Using directives
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AlphaMobileControls;
using System.Collections;
using gpsMe.Classes;
using gpsMe.Utils;
using gpsMe.Properties;
using System.Threading;
using System.Runtime.InteropServices;
using gpsMe.GPS;
#endregion

namespace gpsMe.UI.Forms
{
    /// <summary>
    /// gpsMe navigation form
    /// </summary>
    public partial class gpsMeNavigationForm : AlphaForm
    {
        #region Instance
        /// <summary>
        /// Current gpsMeNavigationForm instance
        /// </summary>
        public static gpsMeNavigationForm Instance { get; private set; }
        #endregion

        #region Controls
        /// <summary>
        /// Image of the toolbar
        /// </summary>
        private AlphaPictureBox toolbarImage;

        /// <summary>
        /// Image of the battery
        /// </summary>
        private AlphaPictureBox batteryImage;

        /// <summary>
        /// Image representing the quality of the gps signal
        /// ** Currently not working due to issues by using the GPS.NET lib **
        /// </summary>
        private AlphaPictureBox gpsSignalImage;

        /// <summary>
        /// Foreground of the hour label
        /// </summary>
        private AlphaLabel hourLabelForeground;

        /// <summary>
        /// Background of the hour label
        /// </summary>
        private AlphaLabel hourLabelBackground;

        /// <summary>
        /// Foreground of the speed label
        /// ** Currently not working due to issues by using the GPS.NET lib **
        /// </summary>
        private AlphaLabel speedLabelForeground;

        /// <summary>
        /// Background of the speed label
        /// ** Currently not working due to issues by using the GPS.NET lib **
        /// </summary>
        private AlphaLabel speedLabelBackground;

        #region GPS.NET issues temporarly patch
        /// <summary>
        /// Foreground of the speed label
        /// ** Currently not working due to issues by using the GPS.NET lib **
        /// </summary>
        private AlphaLabel positionLabelForeground;

        /// <summary>
        /// Background of the speed label
        /// ** Currently not working due to issues by using the GPS.NET lib **
        /// </summary>
        private AlphaLabel positionLabelBackground;
        #endregion

        /// <summary>
        /// Foreground of the altitude label
        /// </summary>
        private AlphaLabel altitudeLabelForeground;
        
        /// <summary>
        /// Background of the altitude label
        /// </summary>
        private AlphaLabel altitudeLabelBackground;
        #endregion

        #region Attributes
        /// <summary>
        /// Images of the battery
        /// 0~4
        /// </summary>
        private Hashtable batteryImages;

        /// <summary>
        /// Images of the battery when power is given by sector
        /// 0~4
        /// </summary>
        private Hashtable powerImages;

        /// <summary>
        /// Image displayed in the battery status picture box when there is no information available about the alimentation of the pda
        /// </summary>
        private AlphaImage noBatteryImage;

        /// <summary>
        /// Images of the gps signal
        /// 0~5
        /// </summary>
        private Hashtable gpsSignalImages;

        /// <summary>
        /// Thread that updates regularly the informations displayed on the toolbar
        /// </summary>
        private static Thread infoUpdateThread;

        /// <summary>
        /// Specifies if the info update thread is currently running
        /// </summary>
        private bool infoUpdateThreadIsActive;
        #endregion

        #region DLL imports
        public class SYSTEM_POWER_STATUS_EX2
        {
            public byte ACLineStatus;
            public byte BatteryFlag;
            public byte BatteryLifePercent;
            public byte Reserved1;
            public uint BatteryLifeTime;
            public uint BatteryFullLifeTime;
            public byte Reserved2;
            public byte BackupBatteryFlag;
            public byte BackupBatteryLifePercent;
            public byte Reserved3;
            public uint BackupBatteryLifeTime;
            public uint BackupBatteryFullLifeTime;
            public uint BatteryVoltage;
            public uint BatteryCurrent;
            public uint BatteryAverageCurrent;
            public uint BatteryAverageInterval;
            public uint BatterymAHourConsumed;
            public uint BatteryTemperature;
            public uint BackupBatteryVoltage;
            public byte BatteryChemistry;
        }
        [DllImport("coredll")]
        private static extern uint GetSystemPowerStatusEx2(SYSTEM_POWER_STATUS_EX2 lpSystemPowerStatus, uint dwLen, bool fUpdate);
        #endregion

        #region Constructor
        /// <summary>
        /// Default constructor
        /// </summary>
        public gpsMeNavigationForm()
        {
            Instance = this;
            this.Menu.Dispose();
            this.InitializeComponent();
            this.InitializeAlphaControls();
            this.InitializeEvents();
            this.InitializeThreads();
        }
        #endregion

        #region Methods / Functions / Events
        #region Initialization
        #region Alpha Controls Initialization
        /// <summary>
        /// Initialization of the AlphaControls of the form
        /// </summary>
        private void InitializeAlphaControls()
        {
            #region Hour label
            this.hourLabelForeground = new AlphaLabel();
            this.hourLabelForeground.Text = gpsMeUtils.CurrentHour;
            this.hourLabelForeground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_FORE_COLOR;
            this.Controls.Add(this.hourLabelForeground);
            this.hourLabelBackground = new AlphaLabel();
            this.hourLabelBackground.Text = gpsMeUtils.CurrentHour;
            this.hourLabelBackground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_BACK_COLOR;
            this.Controls.Add(this.hourLabelBackground);
            #endregion

            #region Altitude label
            this.altitudeLabelForeground = new AlphaLabel();
            this.altitudeLabelForeground.Text = gpsMeLanguage.Instance.AltitudeShortLabel + ": " + gpsMeLanguage.Instance.UnavailableLabel;
            this.altitudeLabelForeground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_FORE_COLOR;
            this.Controls.Add(this.altitudeLabelForeground);
            this.altitudeLabelBackground = new AlphaLabel();
            this.altitudeLabelBackground.Text = this.altitudeLabelForeground.Text;
            this.altitudeLabelBackground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_BACK_COLOR;
            this.Controls.Add(this.altitudeLabelBackground);
            #endregion

            #region Speed label
            this.speedLabelForeground = new AlphaLabel();
            this.speedLabelForeground.Text = gpsMeLanguage.Instance.SpeedShortLabel + ": " + gpsMeLanguage.Instance.UnavailableLabel;
            this.speedLabelForeground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_FORE_COLOR;
            //this.Controls.Add(this.speedLabelForeground);
            this.speedLabelBackground = new AlphaLabel();
            this.speedLabelBackground.Text = this.speedLabelForeground.Text;
            this.speedLabelBackground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_BACK_COLOR;
            //this.Controls.Add(this.speedLabelBackground);
            #endregion

            #region GPS.NET issues temporarly patch
            this.positionLabelForeground = new AlphaLabel();
            this.positionLabelForeground.Text = "Pos." + ": " + gpsMeLanguage.Instance.UnavailableLabel;
            this.positionLabelForeground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_FORE_COLOR;
            this.Controls.Add(this.positionLabelForeground);
            this.positionLabelBackground = new AlphaLabel();
            this.positionLabelBackground.Text = this.positionLabelForeground.Text;
            this.positionLabelBackground.ForeColor = gpsMeNavigationFormProperties.TOOLBAR_LABEL_BACK_COLOR;
            this.Controls.Add(this.positionLabelBackground);
            #endregion

            #region Battery indicator
            this.batteryImages = new Hashtable();
            this.powerImages = new Hashtable();
            for (int iBatteryImageIterator = 0; iBatteryImageIterator < 5; iBatteryImageIterator++)
            {
                this.batteryImages.Add(iBatteryImageIterator, AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\battery" + iBatteryImageIterator + ".png"));
                this.powerImages.Add(iBatteryImageIterator, AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\power" + iBatteryImageIterator + ".png"));
            }
            this.noBatteryImage = AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\noBatteryInformation.png");
            this.batteryImage = new AlphaPictureBox();
            this.batteryImage.Image = noBatteryImage;
            this.batteryImage.Size = new Size(gpsMeNavigationFormProperties.BATTERY_LEVEL_WIDTH, gpsMeNavigationFormProperties.BATTERY_LEVEL_HEIGHT);
            this.Controls.Add(this.batteryImage);
            #endregion

            #region GPS signal
            this.gpsSignalImages = new Hashtable();
            for (int iGpsSignalImageIterator = 0; iGpsSignalImageIterator < 5; iGpsSignalImageIterator++)
            {
                this.gpsSignalImages.Add(iGpsSignalImageIterator, AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\network" + iGpsSignalImageIterator.ToString() + ".png"));
            }
            this.gpsSignalImage = new AlphaPictureBox();
            this.gpsSignalImage.Image = (AlphaImage)this.gpsSignalImages[0];
            this.gpsSignalImage.Size = new Size(gpsMeNavigationFormProperties.GPS_SIGNAL_WIDTH, gpsMeNavigationFormProperties.GPS_SIGNAL_HEIGHT);
            /*
             * Not currently working
             * this.Controls.Add(this.gpsSignalImage);
             */
            #endregion

            #region Toolbar
            this.toolbarImage = new AlphaPictureBox();
            this.toolbarImage.Image = AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\navigationToolbar.png");
            this.Controls.Add(this.toolbarImage);
            #endregion

            #region Cursor
            this.Controls.Add(gpsMeCursor.Instance.Image);
            #endregion

            #region Map
            LoadMap();
            #endregion
        }
        #endregion

        #region Thread and events initialization
        /// <summary>
        /// Initialization of the threads
        /// </summary>
        private void InitializeThreads()
        {
            infoUpdateThread = new Thread(new ThreadStart(InfoUpdateThreadLoop));
            infoUpdateThread.Start();
            infoUpdateThreadIsActive = true;
        }

        /// <summary>
        /// Initialization of the events
        /// </summary>
        private void InitializeEvents()
        {
            this.Click +=new EventHandler(Map_Click);
            this.Closing += new CancelEventHandler(gpsMeNavigationForm_Closing);
            this.GotFocus += new EventHandler(gpsMeNavigationForm_GotFocus);
            this.Resize += new EventHandler(gpsMeNavigationForm_Resize);
            gpsMeGpsProvider.Instance.AltitudeChanged += new EventHandler(GpsProvider_AltitudeChanged);
            //gpsMeGpsProvider.Instance.NumberOfSatellitesChanged += new EventHandler(GpsProvider_NumberOfSatellitesChanged);
            gpsMeGpsProvider.Instance.PositionChanged += new EventHandler(GpsProvider_PositionChanged);
            //gpsMeGpsProvider.Instance.SpeedChanged += new EventHandler(GpsProvider_SpeedChanged);
            gpsMeMap.Instance.MapChanged += new EventHandler(gpsMeMap_MapChanged);
            gpsMeLanguage.Instance.LanguageChanged += new EventHandler(gpsMeLanguage_LanguageChanged);
        }
        #endregion
        #endregion

        #region Map loading
        private void LoadMap()
        {
            if (gpsMeMap.Instance.BitmapSplit)
            {
                for (int iImageGridIterator = 0; iImageGridIterator < 25; iImageGridIterator++)
                {
                    ((gpsMeMapImage)gpsMeMapImageGrid.Instance.SplittedImageGrid[iImageGridIterator]).Image.Click += new EventHandler(Map_Click);
                    this.Controls.Add(((gpsMeMapImage)gpsMeMapImageGrid.Instance.SplittedImageGrid[iImageGridIterator]).Image);
                }
            }
            else
            {
                ((gpsMeMapImage)gpsMeMapImageGrid.Instance.NormalImageGrid).Image.Click += new EventHandler(Map_Click);
                this.Controls.Add(((gpsMeMapImage)gpsMeMapImageGrid.Instance.NormalImageGrid).Image);
            }
        }
        #endregion

        #region Thread loops
        /// <summary>
        /// Executed by the infoUpdateThread
        /// </summary>
        private void InfoUpdateThreadLoop()
        {
            try
            {
                while (true)
                {
                    BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
                    {
                        if (!this.IsDisposed)
                        {
                            this.infoUpdateThreadIsActive = true;
                            #region Hour label update
                            if (this.hourLabelForeground.Text != gpsMeUtils.CurrentHour)
                            {
                                this.hourLabelForeground.Text = gpsMeUtils.CurrentHour;
                                this.hourLabelBackground.Text = gpsMeUtils.CurrentHour;
                            }
                            #endregion

                            #region Battery status update
                            SYSTEM_POWER_STATUS_EX2 oStatus = new SYSTEM_POWER_STATUS_EX2();
                            if (GetSystemPowerStatusEx2(oStatus, (uint)Marshal.SizeOf(oStatus), false) == (uint)Marshal.SizeOf(oStatus))
                            {
                                if (oStatus.ACLineStatus == 1)
                                {
                                    if (!this.batteryImage.Image.Equals((AlphaImage)this.powerImages[((int)(((float)oStatus.BatteryLifePercent / 100) * 4))]))
                                        this.batteryImage.Image = (AlphaImage)this.powerImages[((int)(((float)oStatus.BatteryLifePercent / 100) * 4))];
                                }
                                else
                                {
                                    if (!this.batteryImage.Image.Equals((AlphaImage)this.batteryImages[((int)(((float)oStatus.BatteryLifePercent / 100) * 4))]))
                                        this.batteryImage.Image = (AlphaImage)this.batteryImages[((int)(((float)oStatus.BatteryLifePercent / 100) * 4))];
                                }
                            }
                            #endregion
                        }
                    }));
                    Thread.Sleep(gpsMeNavigationFormProperties.INFO_UPDATE_THREAD_SLEEP);
                }
            }
            catch
            {
                infoUpdateThread.Abort();
            }
        }
        #endregion

        #region Events
        #region Map events
        /// <summary>
        /// Invoked when a new map is loaded
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void gpsMeMap_MapChanged(object p_oSender, EventArgs p_oEventArgs)
        {
            BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                if (this.infoUpdateThreadIsActive)
                    infoUpdateThread.Abort();
                this.Controls.Clear();
                this.InitializeAlphaControls();
                this.InitializeThreads();
                if (gpsMeGpsProvider.Instance.Position != null)
                    gpsMeMapImageGrid.Instance.UpdateGrid(gpsMeGpsProvider.Instance.Position);
                else if (gpsMeMap.Instance.LocationMode == gpsMeMap.LOCATION_MODE_TOP_LEFT_BOTTOM_RIGHT)
                    gpsMeMapImageGrid.Instance.UpdateGrid(gpsMeMap.Instance.LocationTopLeft);
                else
                    gpsMeMapImageGrid.Instance.UpdateGrid(new gpsMeLocationPoint(gpsMeMap.Instance.LocationTopRight.Latitude, gpsMeMap.Instance.LocationBottomLeft.Longitude));
                infoUpdateThread = new Thread(new ThreadStart(InfoUpdateThreadLoop));
                infoUpdateThread.Start();
                infoUpdateThreadIsActive = true;
                this.OnResize(new EventArgs());
            }));
        }
        #endregion

        #region Gps events
        /// <summary>
        /// Invoked when the current speed has changed
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void GpsProvider_SpeedChanged(object p_oSender, EventArgs p_oEventArgs)
        {
            BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                this.speedLabelForeground.Text = gpsMeLanguage.Instance.SpeedShortLabel + ": " + gpsMeGpsProvider.Instance.Speed.ToString() + " Km/h";
                this.speedLabelBackground.Text = this.speedLabelForeground.Text;
            }));
        }

        /// <summary>
        /// Invoked when the current position has changed
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void GpsProvider_PositionChanged(object p_oSender, EventArgs p_oEventArgs)
        {
            BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                gpsMeMapImageGrid.Instance.UpdateGrid(gpsMeGpsProvider.Instance.Position);

                #region GPS.NET issues temporarly patch
                this.positionLabelForeground.Text = "Pos.: " + Math.Round(gpsMeGpsProvider.Instance.Position.Latitude.DegreesValue, 3).ToString() + "°  " + Math.Round(gpsMeGpsProvider.Instance.Position.Longitude.DegreesValue, 3).ToString() + "°";
                this.positionLabelBackground.Text = this.positionLabelForeground.Text;
                #endregion
            }));
        }

        /// <summary>
        /// Invoked when the current number of satellites has changed
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void GpsProvider_NumberOfSatellitesChanged(object p_oSender, EventArgs p_oEventArgs)
        {
            BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                int iImageNumber = (gpsMeGpsProvider.Instance.NumberOfSatellites / 12) * 4;
                if (this.gpsSignalImage.Image.Equals(this.gpsSignalImages[iImageNumber] as AlphaImage))
                    this.gpsSignalImage.Image = this.gpsSignalImages[iImageNumber] as AlphaImage;
            }));
        }

        /// <summary>
        /// Invoked when the current altitude has been changed
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void GpsProvider_AltitudeChanged(object p_oSender, EventArgs p_oEventArgs)
        {
            BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                string sAltitude = Math.Round(gpsMeGpsProvider.Instance.Altitude, 2).ToString();
                if (sAltitude.Contains(','))
                {
                    if (sAltitude.Substring(sAltitude.IndexOf(',') + 1).Length > 2)
                        sAltitude = sAltitude.Substring(0, sAltitude.IndexOf(',') + 2);
                }
                else
                {
                    if (sAltitude.Substring(sAltitude.IndexOf('.') + 1).Length > 2)
                        sAltitude = sAltitude.Substring(0, sAltitude.IndexOf('.') + 2);
                }
                if (sAltitude != "N") // Here to get off a bizarre bogus that displays a "N" before giving the true altitude
                {
                    this.altitudeLabelForeground.Text = gpsMeLanguage.Instance.AltitudeShortLabel + ": " + sAltitude + " m";
                    this.altitudeLabelBackground.Text = this.altitudeLabelForeground.Text;
                }
            }));
        }
        #endregion

        #region Form events
        /// <summary>
        /// Invoked when the map is clicked
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void Map_Click(object p_oSender, EventArgs p_oEventArgs)
        {
            infoUpdateThread.Abort();
            infoUpdateThreadIsActive = false;
            this.Hide();
        }

        /// <summary>
        /// Invoked when the form is resized
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void gpsMeNavigationForm_Resize(object p_oSender, EventArgs p_oEventArgs)
        {
            this.SuspendLayout();
            if (gpsMeGpsProvider.Instance.Position != null)
                gpsMeMapImageGrid.Instance.UpdateGrid(gpsMeGpsProvider.Instance.Position);
            this.toolbarImage.Location = new Point(0, 0);
            this.toolbarImage.Size = new Size(this.Width, gpsMeNavigationFormProperties.TOOLBAR_HEIGHT);
            this.batteryImage.Location = new Point(this.hourLabelForeground.Left - gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER - gpsMeNavigationFormProperties.BATTERY_LEVEL_WIDTH, gpsMeNavigationFormProperties.BATTERY_LEVEL_TOP);
            this.gpsSignalImage.Location = new Point(this.batteryImage.Left - gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER - gpsMeNavigationFormProperties.GPS_SIGNAL_WIDTH, gpsMeNavigationFormProperties.GPS_SIGNAL_TOP);
            this.hourLabelForeground.Location = new Point(this.Width - gpsMeNavigationFormProperties.HOUR_LABEL_LEFT - gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER, gpsMeNavigationFormProperties.HOUR_LABEL_TOP);
            this.hourLabelBackground.Location = new Point(this.Width - gpsMeNavigationFormProperties.HOUR_LABEL_LEFT - gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER + 1, gpsMeNavigationFormProperties.HOUR_LABEL_TOP + 1);
            this.altitudeLabelForeground.Location = new Point(gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER, 0);
            this.altitudeLabelForeground.Size = new Size(this.gpsSignalImage.Left - (gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER * 2) - 1, this.altitudeLabelForeground.Height);
            this.altitudeLabelBackground.Location = new Point(this.altitudeLabelForeground.Left + 1, this.altitudeLabelForeground.Top + 1);
            this.altitudeLabelBackground.Size = this.altitudeLabelForeground.Size;
            this.speedLabelForeground.Location = new Point(gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER, this.toolbarImage.Height / 2);
            this.speedLabelForeground.Size = new Size(this.gpsSignalImage.Left - (gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER * 2) - 1, this.speedLabelForeground.Height);
            this.speedLabelBackground.Location = new Point(this.speedLabelForeground.Left + 1, this.speedLabelForeground.Top + 1);
            this.speedLabelBackground.Size = this.speedLabelForeground.Size;

            #region GPS.NET issues temporarly patch
            this.positionLabelForeground.Location = new Point(gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER, (this.toolbarImage.Height / 2) - 3);
            this.positionLabelForeground.Size = new Size(this.batteryImage.Left - (gpsMeNavigationFormProperties.TOOLBAR_ELEMENTS_BORDER * 2) - 1, this.positionLabelForeground.Height);
            this.positionLabelBackground.Location = new Point(this.positionLabelForeground.Left + 1, this.positionLabelForeground.Top + 1);
            this.positionLabelBackground.Size = this.positionLabelForeground.Size;
            #endregion

            this.ResumeLayout();
        }

        /// <summary>
        /// Invoked when the form is closing
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void gpsMeNavigationForm_Closing(object p_oSender, CancelEventArgs p_oEventArgs)
        {
            infoUpdateThread.Abort();
            infoUpdateThreadIsActive = false;
        }

        /// <summary>
        /// Invoked when the form got the focus
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gpsMeNavigationForm_GotFocus(object sender, EventArgs e)
        {
            if (!this.infoUpdateThreadIsActive)
            {
                infoUpdateThread = new Thread(new ThreadStart(InfoUpdateThreadLoop));
                infoUpdateThread.Start();
                infoUpdateThreadIsActive = true;
            }
        }
        #endregion

        #region Language events
        /// <summary>
        /// Invoked when the user language has been changed
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void gpsMeLanguage_LanguageChanged(object p_oSender, EventArgs p_oEventArgs)
        {
            BeginInvoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                this.altitudeLabelForeground.Text = gpsMeLanguage.Instance.AltitudeShortLabel + ": " + gpsMeLanguage.Instance.UnavailableLabel;
                this.altitudeLabelBackground.Text = this.altitudeLabelForeground.Text;
                this.speedLabelForeground.Text = gpsMeLanguage.Instance.SpeedShortLabel + ": " + gpsMeLanguage.Instance.UnavailableLabel;
                this.speedLabelBackground.Text = this.speedLabelForeground.Text;
                this.positionLabelForeground.Text = "Pos.: " + gpsMeLanguage.Instance.UnavailableLabel;
                this.positionLabelBackground.Text = this.positionLabelForeground.Text;
            }));
        }
        #endregion
        #endregion
        #endregion
    }
}